Rotating Objects in 2D-Space

by Tomas J. Nally

Steelweaver52@aol.com


Home

Tip Corner: Using

Game Programming

Round Buttons

Rotating Objects

LBW: Book Marks

Slide Puzzle

Speech DLL

Addresses

Beginners Programming

Newsletter help

Index

Introduction

This article discusses how to rotate a vector graphic object plotted to a Liberty BASIC GRAPHICBOX, or to a window of type GRAPHICS. For the most part, all we need is a little bit of the geometry that we learned in high school. It would also be helpful, but not necessary, if we have an understanding of polar coordinates, and perhaps an understanding of angles expressed in degrees, and angles expressed in radians.

But before we get into the steps required to rotate an object, let's chat for a minute about vector graphic objects.

Fig 1 - Diamond-shaped object and data, created with Microsoft Excel

What Are "Vector Objects"?

A vector graphic object is different from what we call a bitmap object. A bitmap consists of a collection of lit pixels on a rectangular area of your screen. In fact, the bitmap object is defined on the basis of the color assigned to each individual pixel. Liberty BASIC sprites are examples of bitmap objects.

A vector object (as it will be used in this article) is a collection of lines on a plane, usually arranged to form a familiar object. Each line is defined by its two endpoints, and each endpoint is defined by its x- and y-coordinates on the plane. To define a vector graphic object, you need a table of data holding the coordinates of each point; and a second table of data which provides the IDs for the endpoints of all the lines of the object. In Figure 1 to the right, see a graphic object and two tables of data which define the graphic object.

I have a convention in which I refer to the enpoints of lines as "nodes". I typically call one endpoint of the line the "i-node", while the other endpoint is called the "j-node". The vector object in Figure 1 consists of four nodes and six lines.

I've also discussed nodes, lines and objects in other issues of the Liberty BASIC Newsletter. If you need to supplement the above discussion, see my article called Mapping Real World Coordinates to Screen Coordinates in Issue 112 of the Newsletter.

The Steps To Rotating a Vector Object

Rotating a vector object about a point is no more difficult than rotating the object's nodes about that point, then redrawing all of the object's lines. Here are the required steps, a few of which will be discussed in greater detail further down.

  1. Define the object with nodes and lines. Before object rotation commences, the object must be defined. The x- and y-coordinates of the nodes are best handled if they are stored in two arrays. Let's call these arrays x() and y(). Each line has an i-node and a j-node. Let's store this data in the arrays inode() and jnode().

  2. Select the point around which the object will be rotated. Let's call this point the "Center Of Rotation", or COR. Remember that a point is a position in space, and is defined by its coordinates. In our case, our "space" is the 2D GRAPHICBOX, so our COR will only have two coordinates: an x-coordinate and a y-coordinate. Let's use the following variable names for this coordinate pair: xcor and ycor.

  3. Find the distance between the COR and each node. This must be done for each and every node in the vector object. This operation can be done by using what's commonly called the "distance formula" between any two points, (x1, y1) and (x2, y2).

    distance = SQR((x2 - x1)^2 + (y2 - y1)^2)
    

    These COR-to-node distances are best handled if they are stored in an array. Let's call this array R(). So, in our case, we will use this line of code:

    R(i) = SQR((x(i) - xcor)^2 + (y(i) - ycor)^2}
    

  4. Find the angle of the line between the COR and each node. This must also be done for each and every node in the vector object. This step will be discussed in greater detail below, because it involves use of a trigonometric function not found in Liberty BASIC. Store each of these angles in their own array, alpha(). The alpha() angles will be in radians rather than degrees. In all of the programming languages of which I'm aware, radians is the default unit for angles.

  5. Select the angle of rotation. If the programmer wishes, he can ask his user to input this angle in degrees. However, before the rotation occurs, the angle needs to be converted to radians. Let's store the angle of rotation in the variable, beta.

  6. Add the rotation angle, beta, to each and every alpha(i). Performing this operation will soon allow every node of the object to appear in it's new position, rotated about the COR. In code, this operation will appear as follows:

    alpha(i) = alpha(i) + beta
    

    The new nodal coordinates, though, have not yet been determined. This is done in the next step.

  7. Compute the new nodal coordinates at the object's new position. The new coordinates of the nodes are calculated by using native Liberty BASIC functions:

    x(i) = xcor + R(i)*cos(alpha(i))  'determine the new x-coordinate for each node
    y(i) = ycor + R(i)*sin(alpha(i))  'determine the new y-coordinate for each node
    

    Now for the final step.

  8. Clear the GRAPHICBOX and replot the object at it's rotated location.

More About Step 4: Finding the Angle of the Line Between the Center of Rotation and Each Node

Liberty BASIC and other BASICS have a useful function called ATN(). This function takes as an argument the tangent of an angle, and returns the angle that corresponds to that tangent. However, one limitation of this function is that it will only return an angle between -pi/2 and pi/2. This is inadequate for our purposes, because the nodes of an object will not always conveniently place themselves at an angle residing between -pi/2 and pi/2 from the center of rotation.

Many BASIC programmers have gotten around this problem by writing a custom function which will return an angle anywhere on the compass. The one I've written (and used on other occasions) is called ATAN2(), which is the name the Microsoft Excel uses to accomplish the very same task. ATAN2() requires two arguments, deltaX and deltaY, and returns the arc whose tangent is (deltaY/deltaX).

In our object rotation program, we will use it like this:

deltaX = x(i) - xcor
deltaY = y(i) - ycor
alpha(i) = ATAN2(deltaX, deltaY)

The function ATAN2() will be part of the code in the demonstration program discussed below.

Fig 2 - Screenshot of RotateObj.bas

Demonstration Program: RotateObject.bas

My demo program for this article, RotateObject.bas, can be found in the zip archive for this newsletter. A screenshot of RotateObject.bas is shown on the right.

I decided to write a typical Windows event-driven program for the demo because it was more fun for me, and is usually more fun for the user, too. The eight steps identified above are embedded in the code which handles the various Windows events, such as COMBOBOX and BUTTON clicks. To find the eight steps in the code of the program, look for comments beginning with ** Step 1 ** and ** Step 2 **, and so forth.

The program allows the user to set the location of the COR by designating the coordinates of the COR with a pair of COMBOBOXES. In the GRAPHICBOX, the location of the COR is indicated by a crosshair. The angle of rotation, beta, is also set by using a combo box.

Just below the COMBOBOXES, a pair of RADIOBUTTONS allows the user to select either animated rotation of the object, or instant rotation of the object.

It's possible to rotate the object beyond the borders of the GRAPHICBOX. For this reason, the program provides a way to reset both the COR and the object back to their original locations. To do this, press the button labeled "Reset Object and COR".


Home

Tip Corner: Using

Game Programming

Round Buttons

Rotating Objects

LBW: Book Marks

Slide Puzzle

Speech DLL

Addresses

Beginners Programming

Newsletter help

Index